/*
 ----------------------------------------------------------------------------------
                           "THE BEER-WARE COPYRIGHT LICENSE"
                                     (Revision 43)
                                      -----------
    Rymek [rymek@rymek.org] wrote this file. As long as You retain this notice and
    this file has been sent directly to You by the author, You can do whatever You
    want with this stuff as long as You don't sell or rent it. If we meet some day,
    and You think this stuff is worth it, You can buy me a beer in return :-)
                                                                 __________
                                                                 Paweł Rymaszewski
  ----------------------------------------------------------------------------------
 */

package processing.objects;

import constants.MessageConstants;
import utils.properties.Configuration;

import java.io.File;
import java.util.Date;
import java.util.Map;
import java.util.Observable;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Class holds message search results
 *
 * @author rymek
 *         User: rymek
 *         Date: 30.06.11
 *         Time: 10:10
 */
public class Results extends Observable {

    private final Map<Integer, Map<String, Result>> results = new ConcurrentHashMap<>();  // contains unparsed results - results returned based on time period and processing time criteria
    private final SearchParameters searchParameters;                                      // contains search parameters for this search scope
    private final String executionTime = Configuration.dttmFileFormat.format(new Date()); // contains timestamp of search execution
    private File outputDir;                                                               // contains path to temporary directory where messages bodies are stored

    /**
     * Constructor.
     * Sets reference to search parameters.
     *
     * @param searchParameters search parameters of this Results object
     */
    public Results(SearchParameters searchParameters) {
        this.searchParameters = searchParameters;

        switch (searchParameters.getMessageInfo().getMessageType()) {

            case MessageConstants.MSG_SYNC_MESSAGE: {
                this.results.put(MessageConstants.MSG_REQUEST, new ConcurrentHashMap<String, Result>());
                this.results.put(MessageConstants.MSG_RESPONSE, new ConcurrentHashMap<String, Result>());
                break;
            }

            case MessageConstants.MSG_ASYNC_MESSAGE: {
                this.results.put(MessageConstants.MSG_REQUEST, new ConcurrentHashMap<String, Result>());
                break;
            }
        }
    }

    /**
     * Adds Request to Results and notifies observers
     * about addition
     *
     * @param request request to add
     */
    public void addRequestResult(Result request) {
        request.setMessageInfo(new Message(this.searchParameters.getMessageInfo()));
        this.results.get(MessageConstants.MSG_REQUEST).put(request.getId(), request);
        this.setChanged();
        this.notifyObservers(request);
    }

    /**
     * Adds Response to Results
     *
     * @param response response to add
     */
    public void addResponseResult(Result response) {
        response.setMessageInfo(new Message(this.searchParameters.getMessageInfo()));
        this.results.get(MessageConstants.MSG_RESPONSE).put(response.getId(), new Result(response));
    }

    /**
     * Adds Request and Response to Results and notifies observers
     * about the addition
     *
     * @param request  request to add
     * @param response response to add
     */
    public void addResults(Result request, Result response) {
        request.setMessageInfo(new Message(this.searchParameters.getMessageInfo()));
        response.setMessageInfo(new Message(this.searchParameters.getMessageInfo()));

        this.results.get(MessageConstants.MSG_REQUEST).put(request.getId(), request);
        this.results.get(MessageConstants.MSG_RESPONSE).put(response.getId(), response);

        this.setChanged();
        this.notifyObservers(request);
    }

    public synchronized Map<Integer, Map<String, Result>> getResults() {
        return results;
    }

    public synchronized int getResultCount() {
        return this.results.get(MessageConstants.MSG_REQUEST).size();
    }

    public synchronized SearchParameters getSearchParameters() {
        return searchParameters;
    }

    public synchronized String getExecutionTime() {
        return executionTime;
    }

    public synchronized String getOutputDir() {
        return outputDir.getPath();
    }

    public synchronized File getOutputDirAsFile() {
        return outputDir;
    }

    public synchronized void setOutputDir(String outputDir) {
        this.outputDir = new File(outputDir);
    }

    @Override
    public String toString() {
        return "Results{" +
                "results=" + results +
                ", searchParameters=" + searchParameters +
                ", executionTime='" + executionTime + '\'' +
                ", outputDir='" + outputDir + '\'' +
                '}';
    }
}
